物有本末,事有始終,知所先後,則近道矣。
在這裡我們要介紹檔案結構,在上回中,我們創建了一個專案 proj-iron1, 我們使用 VS. Code 來作編輯,VS. Code 在編輯 Angular 專案時,會在徵求同意後自動加入一些相關於Angular 的擴充插件(extensions), 點選 VS. Code, 左側之工具行,第四個 extensions, 可以看到新增的許多相關於 VS. Code 的插件名稱。
開啟 VS Code 後,用 檔案 > 將資料夾新增至工作區…
然後選擇專案所在的根檔案夾,就可以看到所有的檔案,在編修上會方便許多。我們可以發現,工作區是未命名。
我們可以用 檔案 > 另存工作區為...
將工作區作第一次的儲存, 請留意存入的位置,通常可以存在專案的根路徑,會產生一個副檔名為 .code-workspace 的檔案。
如果要同時編輯兩個以上的專案,也可以另外開啟一個檔案夾來儲存。就是存在哪裡要記得,下回方便使用。
使用 Visual Studio 會相當方便,語法錯誤會提示,輸入資料時會自動提供相應的可能選項。新增元件時,也有選項自動提供,自動創建相關的程式碼。
我們學過,web server 由 index.html (可以透過 angular.json 修改起始檔名) 來執行。
在 src/index.html 我們找到這個檔案,其內容是:
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>ProjIron1</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
<app-root></app-root>
</body>
</html>
在這中間也有一些學問,HTML (HyperText Markup Language) 是一個學問,RWD (Reactive Web Design) 也是一個學問,在現代程式的路上,不能單單只會一個兵器,例如不能只會 Angular / Spring Boot, 就像是一個大石頭要立著,旁邊必須有一些小石頭在旁邊圍著、撐著,才會穩,才立得起來。像 HTML, RWD 就是其中的兩個,其他還有許許多多的小石頭,沒有辦理每個兵器都很精熟,就是學一點、用一點,用一點、學一點。在這系列的文章中,我們期待專注在女主⻆(安室伊春, Angular-StackBlitz-Eclipse-Spring Boot)的身上,其他的,我們就輕輕帶過,大家如果有問題,歡迎提問。
在 index.html 中,<head>
中有兩行指令,
<meta name="viewpoint" ...> 以及 <link rel="icon" ...>
前者是RWD的設定,為了在不同尺寸的畫面中有最佳的畫面呈現。細節我們就不說了,如果大家有興趣,可以看 RWD 相關的介紹。而後者,是設定顯示在標題欄的圖標,如下(左)圖所示:(那個紅底的A字)
顯然,顯示的內容,並沒有寫在 index.html, 那是寫在那裡呢?<app-root></app-root>
,對,就寫在這個標簽的位置,我們現在就要理解一下,這中間是如何串起來的。
一開始,從 src/index.html
著手,我們看見 <app-root></app-root>
在 src/app/app.modules.ts
中的@NgModule, declarations 中,宣告這齣戲裡,有那些 “幕前”的演員(AppComponent),import 則是幕後的演員: (app.modules.ts 記錄所有的演員)
@NgModule({
declarations: [
AppComponent
],
… })
在這裡,又出現了一個陌生人,ts, typescript, 如果讀者不了解,就把他當作一個翻譯,會把 typescript 格式的語法,在執行前轉成 javascript. (當然是為了解決 javascript 有一些不方便的地方)。
我們接著發現
import { AppComponent } from './app.component';
這裡指出了 AppComponent 的來源(相對路徑) 在與 app.modules.ts 相同的路徑(src/app)中,有幾個檔案 app.component (.html, .ts, .css, .spec.ts)
.ts, typescript 檔案,可以視作是幕後操控者;
.html 是幕前顯示的內容;
.css 是顯示的格式設定;
.spec.ts 檔案則是提供單元測試時使用,我們有後會章回會介紹一點點。
這裡又有一個陌生人出現,CSS= Cascading Style Sheet, 這又是一門不小的學問,定義內容以何種方式顯示,例如:文字如何顯示(什麼字型?大小?顏色...),按鍵一般如何顯示,游標置於其上時如何顯示,點選時如何顯示,點選後如何顯示,等等。當然,這水也有相當深度。不過學成不必過十八銅人陣才能下山,現學現賣都可以.
在 app.component.html 中定義了顯示的內容:
<div style="text-align:center">
<h1>
Welcome to {{ title }}!
</h1>
<img width="300" alt="Angular Logo" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyNTAgMjUwIj4KICAgIDxwYXRoIGZpbGw9IiNERDAwMzEiIGQ9Ik0xMjUgMzBMMzEuOSA2My4ybDE0LjIgMTIzLjFMMTI1IDIzMGw3OC45LTQzLjcgMTQuMi0xMjMuMXoiIC8+CiAgICA8cGF0aCBmaWxsPSIjQzMwMDJGIiBkPSJNMTI1IDMwdjIyLjItLjFWMjMwbDc4LjktNDMuNyAxNC4yLTEyMy4xTDEyNSAzMHoiIC8+CiAgICA8cGF0aCAgZmlsbD0iI0ZGRkZGRiIgZD0iTTEyNSA1Mi4xTDY2LjggMTgyLjZoMjEuN2wxMS43LTI5LjJoNDkuNGwxMS43IDI5LjJIMTgzTDEyNSA1Mi4xem0xNyA4My4zaC0zNGwxNy00MC45IDE3IDQwLjl6IiAvPgogIDwvc3ZnPg==">
</div>
<h2>Here are some links to help you start: </h2>
<ul>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/tutorial">Tour of Heroes</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://angular.io/cli">CLI Documentation</a></h2>
</li>
<li>
<h2><a target="_blank" rel="noopener" href="https://blog.angular.io/">Angular blog</a></h2>
</li>
</ul>
<router-outlet></router-outlet>
在這裡我們看見了相關於顯示內容的設定,相信大家可以逐一對應起來,望文生義,不難理解。目前,我們尚未對 <app-root></app-root>
關連起來。另外,<img>
設定了Browser中顯元的圖形,這裡先將圖形轉成Base64 的數碼(用文字檔來傳遞/存取就方便多了),再將這些數碼設定在 src 參數之中,如何將圖形轉成 Base64 數碼,我們就不作介紹,大家可以直接請出 Google。
在第四行裡,我們看見了 {{ title }},雙層大括號 在Angular中代表,顯示 title 所對應的值,但是 title 定義在那裡?答案是 app.component.ts (XXX.html 的變數,定義在 XXX.ts 中)。
仔細看 app.component.ts, export class AppComponent 中定義了 title
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'proj-iron1';
}
在 @Component 中,我們發現,元件顯示的內容是 app.commponent.html, 顯示的位置是 <app-root></app-root>
, 格式由 app.component.css 來設定。在這裡,將 <app-root></app-root>
透過 Selector
關連了進來。然後在 export class AppComponent 定義了外界要取值時,採用的元件名稱,這是我們在 app.module.ts / declarations 中看見的 AppComponent,同時,我們也看見 title 的定義.
整理一下
<app-root></app-root>
接著我們換一些內容,來驗証我們的想法是對的。
結果如下:
如果 Angular 保持在執行中,那 VS Code 修改儲存 (^s) 後,會自動編譯、執行,若 Browser 也維持在連線上,也會自動更新。
修改後之 (src/app/)app.component.html 如下:
<div style="text-align:center">
<h1>{{ title }}</h1>
<img width="300" alt="ithelper Logo" src="assets/ithelper.png">
<h2>This is {{ who }} speaking. </h2>
<h2><a target="_blank" rel="noopener" href="https://ithelp.ithome.com.tw/users/20120951/ironman/2805">Link to IronMan Articles.</a></h2>
<router-outlet></router-outlet>
大家應該注意到了,<router-outlet></router-outlet>
, 是否與 <app-root></app-root>
是不是很像?這就表明...還會/可以拍下集...
修改後之 (src/app/)app.component.ts 如下:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = '美麗的邂逅--與安室....伊春';
who = 'faust';
}
至於像 import { Component } from '@angular/core'
, 對,每一個用到的 “法器”(如用到 “@Component”) 都要 “開光”,才會有法力。而且每一世(每個有用到的檔案),都要開光一次。
Using Angular in Visual Studio Code